Using floating-point equality comparisons is risky. See e.g.
Why don't floating point comparisons work?: C / C++ FAQs & Programming Resources - ProkutFAQ
It's best to compare within a small epsilon value to account for floating-point error, especially in chained calculations such as you have (divide by two, divide by two, ...).
Also, you could do the same thing more simply with something like this.
Code:
#define EPSILON 0.0001
int isPowerOf2(double number) {
double logarithm = log(number) / log(2.0);
double intpart; /* don't care about this value, just throwing it away */
double floatpart = modf(logarithm, &intpart);
return (floatpart < EPSILON);
}
I'm using the
change of base rule here to obtain the logarithm base two of the supplied number. (Note that
log() actually uses base e.) If this number is 2.000 or 3.000 or any integer, then the original number was a power of 2. I use
modf() to obtain the floating-point part of the number and ensure that this is less than some small epsilon number, essentially that it is an integer.
You could generalize this to check for other bases as well. And I didn't know this function existed until I was writing this post, but this could even be done with
frexp().
Just some food for thought . . . .